<?php
namespace App\Exports;

use App\Models\Goods;
use App\Models\OrderToGoods;
use App\Models\PurchaseToMaterial;
use App\Models\RecordMaterial;
use Carbon\Carbon;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Maatwebsite\Excel\Concerns\FromView;

/**
 * Created By FreeAbrams
 * Date: 2020/11/26
 */
class MaterialExport implements FromView
{
	
	protected $timeBetween = [];
	
	public function __construct($timeBetween)
	{
		$this->timeBetween = $timeBetween;
	}
	
	public function view():View
	{
		//$temp = $this->data($this->timeBetween);
		$input = $this->input($this->timeBetween);
		$output = $this->output($this->timeBetween);

		foreach ($input as $key => $value) {
			if(!isset($output[$key])){
				$output[$key] = 0;
			}
		}
		foreach ($output as $key => $value) {
			if(!isset($input[$key])){
				$output[$key] = 0;
			}
		}
//dd($input,$output);
		return view('admin.export.material-export-table', [
			'input' => $input,
			//'makeGoods' => $temp['makeGoods'],
			'output' => $output
			]);
	}
	
	public function data($timeBetween)
	{
		//$timeBetween = [];
		// 进仓库原料价格
		$input = PurchaseToMaterial::whereBetween('created_at', $timeBetween)
				->with(['recordmaterial' => function($q){
					$q->where('type', 1);// 1采购2消耗
				}])
			    ->selectRaw('Month(created_at) as date, sum(unit_price * number) as price')
			    ->groupBy('date')
			    ->get();
		//dd($input);
		// 生成商品原料价格
		$makeGoods = PurchaseToMaterial::whereBetween('created_at', $timeBetween)
			    ->whereHas('recordmaterial', function (Builder $query){
			        $query->where('type', 2);// 1采购2消耗
			    })
			    ->selectRaw('Month(created_at) as date, sum(unit_price * number) as price')
			    ->groupBy('date')
			    ->get();
		
		$goods =OrderToGoods::with(['goods' => function($q){
			$q->withTrashed()->with(['goodsToMaterials' => function($q) {
				$q->with(['purchaseToMaterials' => function($q){
					$q->orderBy('created_at', 'desc');
				}])->withPivot('number')
				;}]);
		}])->whereBetween('created_at', $timeBetween)
			->get();
		
		$goods = $goods->map(function ($item, $key) {
			$time = New Carbon($item->created_at);
			$item->date = (int)$time->format('m');
			return $item;
		});

		if (count($goods)) {
			foreach ($goods->groupBy('date') as $k => $v){
				static  $output = [];
				$output[$k] = $this->outputPrice($v->groupBy('goods_id'));
			}
		} else {
			$output = [];
		}
		//$output = collect($goodsPrice)->sum();
		//dd($input, $makeGoods, $output);
		return $data = [
			'input' => $input,
			'makeGoods' => $makeGoods,
			'output' => $output
		];
	}
	
	// 计算毛利润
	public function outputPrice($groupByGoodsId)
	{
		//$goods->groupBy('goods_id')
		foreach ($groupByGoodsId as $k => $v)
		{
			// 卖出的商品数量
			static $goodsCollection = [];
			// 毛利润
			static $goodsPrice = [];
			$goodsCollection[$v[0]->goods->name] = $v->count('number');
			$goodsPrice[$v[0]->goods->name] = 0;
			$goodsNum = $goodsCollection[$v[0]->goods->name];
			// 商品材料用量
			static $goodsMaterialCost = [];
			foreach ($v as $key => $val){
				$goodsToMaterials = $val->goods->goodsToMaterials;
				$number = 0;
				$unit_price = 0;
				foreach ($goodsToMaterials as $value)
				{
					// 判断用料是否已经超过第一批库存生成商品数 = 第一批库存毛利 + 第二批毛利 + 第三..
					foreach ($value->purchaseToMaterials as $purchase) {
						$price = 0;
						if($goodsNum - $purchase->sell > 0){
							$price += $purchase->sell * $purchase->unit_price;
							$goodsNum = $goodsNum - $purchase->sell;
						} else {
							$price += $goodsNum * $purchase->unit_price;
							
							$goodsPrice[$v[0]->goods->name] = $price;
							break;
						}
					}
				}
			}
		}
		return collect($goodsPrice)->sum();
	}

	private function getRecordMaterials()
	{
		$start = Carbon::now();
		$end = Carbon::now();
		$timeBetween = [$start->startOfYear, $end->endOfyear];
		$record = RecordMaterial::whereBetween($timeBetween)
									->where(['style' => 2, 'type' => 2])->all();

	}

	private function input($timeBetween)
	{
        $record = RecordMaterial::whereBetween('created_at', $timeBetween)
	                                ->with(['getUnitPrice:id,unit_price'])
                                    ->where(['style' => 1, 'type' => 1])
	                                ->get();
        // groupBy Month
	    $record->map(function ($item) {
	    	$time = New Carbon($item->created_at);
	    	$item->date = (int)$time->format('m');
	    });

	    foreach ($record->groupBy('date') as $k => $v)
	    {
	        static $price = [];
	        $v->map(function ($item) use (&$price, $k){
	            if(isset($price[$k])){
	                $price[$k] += $item->number * $item->getUnitPrice->unit_price;
	            } else{
	            	$price[$k] = $item->number * $item->getUnitPrice->unit_price;
	            }
	        });
	    }
        return collect($price);
	}

	private function output($timeBetween)
	{
        $record = RecordMaterial::whereBetween('created_at', $timeBetween)
	                                ->with(['getUnitPrice:id,unit_price'])
                                    ->where(['style' => 2, 'type' => 2])
	                                ->get();
        // groupBy Month
	    $record->map(function ($item) {
	    	$time = New Carbon($item->created_at);
	    	$item->date = (int)$time->format('m');
	    });
	    
	    foreach ($record->groupBy('date') as $k => $v)
	    {
	        static $price = [];
	        $v->map(function ($item) use (&$price, $k){
	            if(isset($price[$k])){
	                $price[$k] += $item->number * $item->getUnitPrice->unit_price;
	            } else{
	            	$price[$k] = $item->number * $item->getUnitPrice->unit_price;
	            }
	        });
	    }
        return collect($price);
	}
}